﻿using System;
using System.Collections.Generic;

namespace YJKGridTopologyCal.Index.Sweepline
{
	public class SweepLineIndex
	{
		public void Add(SweepLineInterval sweepInt)
		{
			SweepLineEvent sweepLineEvent = new SweepLineEvent(sweepInt.Min, null, sweepInt);
			this._events.Add(sweepLineEvent);
			this._events.Add(new SweepLineEvent(sweepInt.Max, sweepLineEvent, sweepInt));
		}

		private void BuildIndex()
		{
			if (this._indexBuilt)
			{
				return;
			}
			this._events.Sort();
			for (int i = 0; i < this._events.Count; i++)
			{
				SweepLineEvent sweepLineEvent = this._events[i];
				if (sweepLineEvent.IsDelete)
				{
					sweepLineEvent.InsertEvent.DeleteEventIndex = i;
				}
			}
			this._indexBuilt = true;
		}

		public void ComputeOverlaps(ISweepLineOverlapAction action)
		{
			this._nOverlaps = 0;
			this.BuildIndex();
			for (int i = 0; i < this._events.Count; i++)
			{
				SweepLineEvent sweepLineEvent = this._events[i];
				if (sweepLineEvent.IsInsert)
				{
					this.ProcessOverlaps(i, sweepLineEvent.DeleteEventIndex, sweepLineEvent.Interval, action);
				}
			}
		}

		private void ProcessOverlaps(int start, int end, SweepLineInterval s0, ISweepLineOverlapAction action)
		{
			for (int i = start; i < end; i++)
			{
				SweepLineEvent sweepLineEvent = this._events[i];
				if (sweepLineEvent.IsInsert)
				{
					SweepLineInterval interval = sweepLineEvent.Interval;
					action.Overlap(s0, interval);
					this._nOverlaps++;
				}
			}
		}

		private readonly List<SweepLineEvent> _events = new List<SweepLineEvent>();

		private bool _indexBuilt;

		private int _nOverlaps;
	}
}
